﻿using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Raytracer.Generator;
using RaytracerLib;
using RaytracerLib.MathLib;
using RaytracerLib.RenderableObjects;
using RaytracerLib.Volumes;
using RaytracerLib.Samplers;

namespace RaytracerTest
{
    [TestClass]
    public class VolumesOperationsTest : TestBase
    {
        [TestMethod]
        public void Volumes_Operations_Test()
        {
            SphereObject sphere = new SphereObject(Vector3.XAXIS, Vector3.YAXIS)
            {
                Pos = Vector3.ZERO,
                Radius = 1, 
                Name = "sphere"
            };

            var scene = new Scene();
            scene.RenderableObjects.Add(sphere);

            var v1 = VolumesFactory.Transform(null, Matrix4.Identity);
            var v2 = VolumesFactory.Solid(1);

            sphere.DefaultMaterial = TestMaterials.Shiny("shiny", ColorFloat.SRGB_Green);
            sphere.DefaultMaterial.Diffuse = v1;

            Volume.InsertAfter(v1, v2);
            Assert.AreSame(null, v1.Parent);
            Assert.AreSame(v1, v2.Parent);
            Assert.AreSame(v2, v1.Children.First());
            Assert.AreEqual(0, v2.Children.Count());

            var leaves = Volume.GetLeaves(sphere.DefaultMaterial.Ambient as Volume);
            Assert.AreEqual(1, leaves.Count);
            Assert.AreSame(leaves.First(), sphere.DefaultMaterial.Ambient);

            var vn1 = VolumesFactory.Transform(null, Matrix4.Identity);
            Volume.InsertBefore(sphere.DefaultMaterial, v2, vn1);
            Assert.AreSame(sphere.DefaultMaterial.Diffuse, v1);
            Assert.AreSame(vn1, v1.Children.First());
            Assert.AreSame(v2, vn1.Children.First());
            Assert.AreSame(null, v1.Parent);
            Assert.AreSame(v1, vn1.Parent);
            Assert.AreSame(vn1, v2.Parent);

            var vn2 = VolumesFactory.Transform(null, Matrix4.Identity);
            Volume.InsertBefore(sphere.DefaultMaterial, v1, vn2);
            Assert.AreSame(sphere.DefaultMaterial.Diffuse, vn2);
            Assert.AreSame(v1, vn2.Children.First());
            Assert.AreSame(vn1, v1.Children.First());
            Assert.AreSame(null, vn2.Parent);
            Assert.AreSame(vn2, v1.Parent);
            Assert.AreSame(v1, vn1.Parent);
        }
    }
}